define(function(require, exports, module) {

  var Backbone = require('backbone');
  var $ = require('jquery');
  var _ = require('underscore');
  var jsonview = require('jsonview');
  var ce = require('v/graph-zrender/topo/util/createEl')

  var flow = require('js/link/flow')
  var link = require('js/link/index')
  var bezier = require('js/link/bezier')
  const { QBTEquB24ac, QBTEquSolution, quadraticBezier, getCurvePointsByX } = bezier

  var LINE_TYPE = 'curve'
  var scale = 1

  function main() {
    var $app = $('<div id="app">');
    $('#main').html($app);
    draw($app);
  }

  var points = [[100,100],[150,100],[150,150],[600,350]];

  var p0 = points[0];
  var p1 = points[3];
  points = [p0, [p0[0], p1[1]], p1]

  function draw($el) {

    let xMark = 400;

    var $canvas = g.newCanvas().css({
      'background-color': g.bgColor
    }).mousemove(function(e) {
      let boundry = $canvas[0].getBoundingClientRect();
      let mouseX = e.clientX - boundry.left;
      let mouseY = e.clientY - boundry.top;
      xMark = mouseX
    }).click(function(e) {
      let boundry = $canvas[0].getBoundingClientRect();
      let mouseX = e.clientX - boundry.left;
      let mouseY = e.clientY - boundry.top;

      link.didClickLine(points, mouseX, mouseY, scale)
    });
    var ctx = $canvas[0].getContext('2d');
    ctx.clearRect(0, 0, env.w, env.h);

    $el.append($canvas)

    var $canvas2 = g.newCanvas().css({
      'background-color': g.bgColor
    });
    var ctx2 = $canvas2[0].getContext('2d');
    ctx2.clearRect(0, 0, env.w, env.h);

    $el.append($canvas2)

    var animate = flow.animationPlus({
      points: points,
      type: 'bezier'
    }, 2, 10)
    var bezierAnimat = bezier.bezierAnimation(points)

    function step() {
      requestAnimationFrame(step);
      var flowPoints = bezierAnimat.get()
      var flowPoints2 = animate.get()
      drawPoints(ctx, points, flowPoints, xMark, true)
      drawPoints(ctx2, points, flowPoints2, xMark)
    }

    requestAnimationFrame(step);
  }

  function drawPoints(ctx, points, flowPoints, xMark, flag) {
    ctx.clearRect(0, 0, env.w, env.h);
    
    ctx.beginPath()
    ctx.strokeStyle = 'lightgreen'
    ctx.lineWidth = 1;
    ctx.moveTo(xMark * scale, 0);
    ctx.lineTo(xMark * scale, g.h)
    ctx.stroke();
    ctx.closePath();

    if (flag) { // 窄的发光线压住宽的白线
      ctx.beginPath();
      ctx.lineWidth = 1;
      ctx.strokeStyle = 'white'
      ctx.moveTo(points[0][0] * scale, points[0][1] * scale)
      if (LINE_TYPE === 'curve') {
        link.drawCurve(ctx, points[1], points[2], scale)
      } else {
        for (var i = 1; i < points.length; i++) {
          ctx.lineTo(points[i][0], points[i][1]);
        }
      }
      ctx.stroke();
      ctx.closePath();

      ctx.beginPath();
      ctx.lineWidth = 0.5;
      ctx.strokeStyle = g.lineColor
      ctx.shadowColor = g.lineColor;
      ctx.shadowBlur = 3;
      ctx.moveTo(points[0][0] * scale, points[0][1] * scale)
      if (LINE_TYPE === 'curve') {
        link.drawCurve(ctx, points[1], points[2], scale)
      } else {
        for (var i = 1; i < points.length; i++) {
          ctx.lineTo(points[i][0], points[i][1]);
        }
      }
      ctx.stroke();
      ctx.closePath();
    } else { // 窄的白线压住宽的发光线
      ctx.beginPath();
      ctx.lineWidth = 1;
      ctx.strokeStyle = g.lineColor
      ctx.shadowColor = g.lineColor;
      ctx.shadowBlur = 3;
      ctx.moveTo(points[0][0] * scale, points[0][1] * scale)
      if (LINE_TYPE === 'curve') {
        link.drawCurve(ctx, points[1], points[2], scale)
      } else {
        for (var i = 1; i < points.length; i++) {
          ctx.lineTo(points[i][0], points[i][1]);
        }
      }
      ctx.stroke();
      ctx.closePath();

      ctx.beginPath();
      ctx.lineWidth = 0.5;
      ctx.strokeStyle = 'white'
      ctx.moveTo(points[0][0] * scale, points[0][1] * scale)
      if (LINE_TYPE === 'curve') {
        link.drawCurve(ctx, points[1], points[2], scale)
      } else {
        for (var i = 1; i < points.length; i++) {
          ctx.lineTo(points[i][0], points[i][1]);
        }
      }
      ctx.stroke();
      ctx.closePath();
    }

    _.map(flowPoints, function(point) {
      drawPoint(ctx, point);
    })


    if (xMark > points[0][0] && xMark < points[2][0]) {
      const curvePoints = getCurvePointsByX(xMark, points, scale)
      _.map(curvePoints, function(point) {
        drawPoint(ctx, point, 2.5);
      })
    }
  }

  function drawPoint(ctx, point, r, scale) {
    r = r || 2;
    scale = scale || 1;
    ctx.beginPath();
    ctx.fillStyle = 'white';
    ctx.arc(point[0] * scale, point[1] * scale, r * scale, 0, 2 * Math.PI, false)
    ctx.fill();
    ctx.closePath();
  }

  return main;
})
